#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <pthread.h>
#include <strings.h>

#define IMAGE_COUNT 10
#define IMAGE_WIDTH 40
#define IMAGE_HEIGHT 40
#define PIXEL_SIZE 3 // RGB
#define GAP 40 // 图片间隔

void mode(long long dt,float tm,float hu);
int load_image_data(const char *filename, unsigned char *buffer);
void display_image(unsigned char *image, int x_offset, int y_offset);
int rec_display(void);
extern int wifi_tcp_init();
extern void* read_app_data(void* arg);

unsigned char image_data[IMAGE_COUNT][IMAGE_WIDTH * IMAGE_HEIGHT * PIXEL_SIZE];
unsigned char sum[12] = { 0 };
int wifi_sockfd;
struct sockaddr_in server, client;
int wifi_connfd;

int wifi_tcp_init()
{	//1，创建wifi tcp网络协议套接字启动文件：sockfd
	wifi_sockfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	
	int opt = 1;
	setsockopt(wifi_sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt));
	
	//2，绑定当前wifi服务器ip地址和端口
	bzero(&server,sizeof(server));
	
	server.sin_family = AF_INET;
	server.sin_port = htons(1159);
	server.sin_addr.s_addr = htonl(INADDR_ANY); //可以接受任何地址的数据
	
	//inet_pton(AF_INET,argv[1],&Rose_addr.sin_addr);
	
	bind(wifi_sockfd,(struct sockaddr *)&server,sizeof(server));
	
	//3，设置监听，用于限制客户端连接数量
	listen(wifi_sockfd,5);
	
	return  wifi_sockfd;
}

void* read_app_data(void* arg)
{
	pthread_detach(pthread_self());
	int x, y;
    int count = 0;
	
	//4. 等待客户端连接：connfd: 
	socklen_t len= sizeof(client);  //通用结构体变量地址
	
	wifi_connfd = accept(wifi_sockfd,(struct sockaddr *)&client,&len);
	
	if(wifi_connfd > 0) {
		printf("new connect!\n");
	}
	
	//5. 不断接受客户端消息
	char buf[100];
	//char buf[800*640*4];
	//struct buffer currnet_buf;
	
	
	while(1) {
		bzero(buf,100);
		//read(connfd, buf, 800*640*4);
		//read(connfd, currnet_buf.start, currnet_buf.length);
		recv(wifi_connfd,buf,sizeof(buf),0);
		
		printf("from client : %s\n",buf);
		
		if(strncmp(buf,"quit",4) == 0)
		{
			break;
		}
		
		if (strncmp(buf, "video",5) == 0) {
			//注意mplayer程序和11.avi文件是否存在
			system("mplayer /root/data/11.avi");
		}
	}
	
	close(wifi_connfd);
	
	pthread_exit(NULL);
}


int rec_display(){
    FILE* pf = fopen("1.txt", "r");
    long long da=0;
    float tm=0;
    float hu=0;
    while (fscanf(pf, "%lld %f %f", &da, &tm, &hu) != EOF){
    mode(da,tm,hu);
    char filename[10];
    for (int i = 0; i < IMAGE_COUNT; i++) {
        sprintf(filename, "%d.bmp", i);
        if (load_image_data(filename, image_data[i]) == -1) {
            printf("加载%s文件失败\n", filename);
            return -1;
        }
    }

    int x_offset = 40, y_offset = 60;
    // image_data[i] 包含第 i 张图片的像素数据
    // 你可以按需使用它们，例如：
    sleep(2);
    for(int k=0;k<12;k++){
        if (sum[k] >= IMAGE_COUNT) {
            printf("sum[%d]的值%d超出范围\n", k, sum[k]);
            return -1;
        }
        display_image(image_data[sum[k]], x_offset, y_offset);
        x_offset += GAP;
        if(k==7){
            x_offset += GAP;
        }else if(k==9){
            x_offset += GAP;
        }
    }
    }
    fclose(pf);
}

void mode(long long dt,float tm,float hu)
{
    int a1 = (int)dt;
    int a2=(int)tm;
    int a3=(int)hu;
    int i = 0;
    for(int i=7;i>=0;i--)
    {
        char tmp=a1%10;
        a1/=10;
        sum[i]=tmp;
    }

    for(int i=9;i>=8;i--)
    {
        char tmp=a2%10;
        a2/=10;
        sum[i]=tmp;
    }

    for(int i=11;i>=10;i--)
    {
        char tmp=a3%10;
        a3/=10;
        sum[i]=tmp;
    }
}

int load_image_data(const char *filename, unsigned char *buffer) {
    int fd = open(filename, O_RDONLY);
    if (fd == -1) {
        printf("打开%s文件失败\n", filename);
        return -1;
    }
        // 跳过位图文件头和位图信息头
    lseek(fd, 54, SEEK_SET);

    int ret = read(fd, buffer, IMAGE_WIDTH * IMAGE_HEIGHT * PIXEL_SIZE);
    if (ret == -1) {
        printf("读取%s文件失败\n", filename);
        close(fd);
        return -1;
    }
    if (ret != IMAGE_WIDTH * IMAGE_HEIGHT * PIXEL_SIZE) {
        printf("读取%s文件数据量不正确\n", filename);
        close(fd);
        return -1;
    }

    close(fd);
    return 0;
}

void display_image(unsigned char *image, int x_offset, int y_offset) {
    int fd_fb0 = open("/dev/fb0", O_RDWR);
    if (fd_fb0 == -1) {
        printf("打开%s文件失败\n", "/dev/fb0");
        return;
    }

    int *p_main_mmap = mmap(NULL, 800 * 480 * 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb0, 0);
    if (p_main_mmap == MAP_FAILED) {
        printf("映射失败!\n");
        close(fd_fb0);
        return;
    }

    for (int y = 0; y < IMAGE_HEIGHT; y++) {
        for (int x = 0; x < IMAGE_WIDTH; x++) {
            int image_index = (IMAGE_HEIGHT - 1 - y) * IMAGE_WIDTH +  x;
            int screen_index = (y_offset + y) * 800 + (x_offset + x);
            p_main_mmap[screen_index] = image[image_index * 3 + 0] << 0 | image[image_index * 3 + 1] << 8 | image[image_index * 3 + 2] << 16 | 0x00 << 24;
        }
    }

    munmap(p_main_mmap, 800 * 480 * 4);
    close(fd_fb0);
}

void send_login(int socket_fd, const char* username, const char* password) {
    char data[200];
    snprintf(data, sizeof(data), "login: %s password: %s", username, password);
    send(socket_fd, data, strlen(data), 0);
}

void send_register(int socket_fd, const char* username, const char* password) {
    char data[200];
    snprintf(data, sizeof(data), "register: %s password: %s", username, password);
    send(socket_fd, data, strlen(data), 0);
}

void send_data(int socket_fd) {
    FILE* pf = fopen("1.txt", "r");
    long long  msg[3] = {0};
    long long da=0;
    float tm=0;
    float hu=0;
    if (pf != NULL) {
        while (fscanf(pf, "%lld %f %f", &da, &tm, &hu) != EOF) {
            // 在这里处理日期和时间
            msg[0]=da;
            msg[1]=tm;
            msg[2]=hu;
            if(send(socket_fd, msg, sizeof(msg), 0) < 0) {
                perror("send failed");
                exit(-2);
            }else{
            printf("消息已发送\n");
            }
        }
    } else {
        perror("open\n");
        exit(-1);
    }
    fclose(pf);
    printf("发送完成,1.txt已关闭\n");
    msg[0]=1;
    msg[1]=2;
    msg[2]=3;
    send(socket_fd, msg, sizeof(msg), 0);
    printf("已向服务机传送结束标志");
}

void rec_data(int socket_fd) {
    FILE* file = fopen("1.txt", "w");
    if (file == NULL) {
        perror("Failed to open file");
        return;
    }

    long long msg[3];
    ssize_t numBytesRcvd;

    while(1) {
        
        memset(msg, 0, sizeof(msg)); // 初始化数组，数组中的值全部赋值为0
        
        numBytesRcvd = recv(socket_fd, msg, sizeof(msg), 0);
        if(numBytesRcvd < 0) {
            perror("recv failed");
            break;
        } else if(numBytesRcvd == 0) {
            printf("Server disconnected\n");
            break;
        }

        if(msg[0]!=0&msg[1]!=0&msg[2]!=0) {

            printf("Received: %lld %f %f\n", msg[0],(float)msg[1],(float)msg[2]);
            fprintf(file, "%lld %f %f\n", msg[0],(float)msg[1],(float)msg[2]);
            fflush(file); // 确保数据被写入到文件中
        } else {
            fclose(file);
            FILE* file = fopen("1.txt", "w+");
            printf("Received an empty message\n");
        }
        rec_display();
    }

    fclose(file);
}

int main(int argc, char *argv[]) {
    pthread_t wifi_tcp_tid;
    wifi_tcp_init();
    pthread_create(&wifi_tcp_tid, NULL, read_app_data, NULL);
    int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    if(socket_fd < 0) {
        perror("socket creation failed");
        return -1;
    }

    struct sockaddr_in srvaddr;
    srvaddr.sin_family = AF_INET;
    srvaddr.sin_port = htons(55555);
    srvaddr.sin_addr.s_addr = inet_addr("192.168.64.7");

    if(connect(socket_fd, (struct sockaddr *)&srvaddr, sizeof(srvaddr)) < 0) {
        perror("connect failed");
        return -1;
    }

    printf("连接成功\n");

    char choice[10];
    printf("Do you want to register or login? ");
    fgets(choice, sizeof(choice), stdin);
    choice[strcspn(choice, "\n")] = 0;

    char username[1024];
    printf("Enter username: ");
    fgets(username, sizeof(username), stdin);
    username[strcspn(username, "\n")] = 0;

    char password[1024];
    printf("Enter password: ");
    fgets(password, sizeof(password), stdin);
    password[strcspn(password, "\n")] = 0;

    if (strncmp(choice, "register", 8) == 0) {
        send_register(socket_fd, username, password);
        exit(0);

    } else if (strncmp(choice, "login", 5) == 0) {
    send_login(socket_fd, username, password);
    }
    // 接收服务器的确认消息
    char buffer[1024];
    recv(socket_fd, buffer, sizeof(buffer), 0);
    if (strncmp(buffer, "Login successful", 16) == 0) {
        printf("已经接收登录成功，开始发送\n");
        // 如果接收到登录成功的确认消息，发送温湿度数据
        send_data(socket_fd);}

        while(1){
            rec_data(socket_fd);
        }

        close(socket_fd);
        pthread_join(wifi_tcp_tid, NULL);

        return 0;
}
